﻿using DynORM.BLLMapper.Helpers;
using DynORM.Enums;
using DynORM.Interfaces.BLLMapper.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DynORM.ER.Mappers
{
    public class EntityRelation
    {
        public static void Read(object bllObj, string connectionString, DBMSTypes dbmsType)
        {
            LazyLoadStatus.MarkAsLoading(bllObj);

            ObjectAndRowAux.GetInstance(dbmsType).InitBLLObjFKObjects(connectionString, bllObj);

            LazyLoadStatus.MarkAsLoaded(bllObj);
        }

        public static IEnumerable<object> GetChildren(object bllObj)
        {
            List<object> result = new List<object>();
            IEnumerable<Tuple<int, object, RelationQuantity>> oneToManyChildren = ObjectAndRowAux.GetOneToManyChildsFromObj(bllObj);
            foreach (Tuple<int, object, RelationQuantity> t in oneToManyChildren)
                result.Add(t.Item2);
            IEnumerable<Tuple<int, object, RelationQuantity>> manyToManyChildren = ObjectAndRowAux.GetManyToManyChildsFromObj(bllObj);
            foreach (Tuple<int, object, RelationQuantity> t in manyToManyChildren)
                result.Add(t.Item2);
            return result;
        }

        public static IEnumerable<Tuple<int, object, RelationQuantity>> GetChildrenExtended(object bllObj)
        {
            List<Tuple<int, object, RelationQuantity>> result = new List<Tuple<int, object, RelationQuantity>>();
            IEnumerable<Tuple<int, object, RelationQuantity>> oneToManyChildren = ObjectAndRowAux.GetOneToManyChildsFromObj(bllObj);
            foreach(Tuple<int, object, RelationQuantity> t in oneToManyChildren)
                result.Add(new Tuple<int,object,RelationQuantity>(t.Item1, t.Item2, t.Item3));
            IEnumerable<Tuple<int, object, RelationQuantity>> manyToManyChildren = ObjectAndRowAux.GetManyToManyChildsFromObj(bllObj);
            foreach (Tuple<int, object, RelationQuantity> t in manyToManyChildren)
                result.Add(new Tuple<int, object, RelationQuantity>(t.Item1, t.Item2, t.Item3));
            return result;
        }

        public static IEnumerable<object> GetChildsFromObjExcludeManyToMany(object bllObj)
        {
            //exclude many-to-manyis used in deletion logic to make it similar to DB delete cascade fk constraint's parameter
            List<object> result = new List<object>();
            IEnumerable<Tuple<int, object, RelationQuantity>> oneToManyChildren = ObjectAndRowAux.GetOneToManyChildsFromObj(bllObj);
            foreach (Tuple<int, object, RelationQuantity> t in oneToManyChildren)
                result.Add(t.Item2);
            return result;
        }

        public static IEnumerable<Tuple<int, object, RelationQuantity>> GetChildsFromObjExcludeManyToManyExtended(object bllObj)
        {
            //exclude many-to-manyis used in deletion logic to make it similar to DB delete cascade fk constraint's parameter
            List<Tuple<int, object, RelationQuantity>> result = new List<Tuple<int, object, RelationQuantity>>();
            IEnumerable<Tuple<int, object, RelationQuantity>> oneToManyChildren = ObjectAndRowAux.GetOneToManyChildsFromObj(bllObj);
            foreach (Tuple<int, object, RelationQuantity> t in oneToManyChildren)
                result.Add(new Tuple<int, object, RelationQuantity>(t.Item1, t.Item2, t.Item3));
            return result;
        }

        public static void ResetAll(object bllObj, string connectionString, DBMSTypes dbmsType)
        {
            ObjectAndRowAux.GetInstance(dbmsType).DeleteAllRelation(bllObj, connectionString);
        }

        public static void Store(object parent, string connectionString, DBMSTypes dbmsType)
        {
            ObjectAndRowAux.GetInstance(dbmsType).StoreChildren(parent, connectionString);
        }


    }
}
